package com.zhai.boot.service;

import com.zhai.boot.common.EsConstant;
import com.zhai.boot.common.LogConstant;
import com.zhai.boot.common.ServiceResult;
import com.zhai.boot.dao.es.DealESDao;
import com.zhai.boot.domain.es.DealEs;
import com.zhai.boot.domain.in.DealBatchSaveIn;
import com.zhai.boot.domain.in.DealDelIn;
import com.zhai.boot.domain.in.DealGridIn;
import com.zhai.boot.domain.in.DealSaveIn;
import com.zhai.boot.util.BigDecimalUtil;
import com.zhai.boot.util.JSONUtil;
import com.zhai.boot.util.ObjectUtil;
import com.zhai.boot.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Created by 翟凤玺
 * @package com.zhai.boot.service
 * @project-name zhai-boot
 * @description 交易服务实现
 * @create-datetime 2020-5-8 09:59
 */
@Slf4j
@Service
public class DealSerImpl implements DealSer {

    private static final String BUSINESS_NAME = "【交易服务】";
    private static final String METHOD_SAVE = "（保存）";
    private static final String METHOD_BATCH_SAVE = "（批量保存）";
    private static final String METHOD_DEL = "（删除）";
    private static final String METHOD_GRID = "（分页查询）";

    @Autowired
    DealESDao dealESDao;

    @Autowired
    private ElasticsearchTemplate esTemplate;

    @Override
    public ServiceResult save(DealBatchSaveIn.DealSaveIn in) {
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_SAVE, LogConstant.IN, JSONUtil.toStr(in)));
        DealEs dealES = ObjectUtil.copy(in, DealEs.class);
        dealES.setAmount(BigDecimalUtil.initDecimal(in.getAmount()));
        dealES.setCreateTime(new Date());
        DealEs save = dealESDao.save(dealES);
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_SAVE, LogConstant.RESULT, LogConstant.SUCCESS, JSONUtil.toStr(save)));
        return ServiceResult.success();
    }

    @Override
    public ServiceResult batchSave(DealBatchSaveIn in) {
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_BATCH_SAVE, LogConstant.IN, JSONUtil.toStr(in)));
        List<DealBatchSaveIn.DealSaveIn> batch = in.getBatch();
        List<DealEs> saves = new ArrayList<>(batch.size());
        for (DealBatchSaveIn.DealSaveIn saveIn : batch) {
            DealEs dealES = ObjectUtil.copy(saveIn, DealEs.class);
            dealES.setAmount(BigDecimalUtil.initDecimal(saveIn.getAmount()));
            dealES.setCreateTime(new Date());
            saves.add(dealES);
        }
        dealESDao.saveAll(saves);
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_BATCH_SAVE, LogConstant.RESULT, LogConstant.SUCCESS, JSONUtil.toStr(saves)));
        return ServiceResult.success();
    }

    @Override
    public ServiceResult del(DealDelIn in) {
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_DEL, LogConstant.IN, JSONUtil.toStr(in)));
        DealEs dealES = ObjectUtil.copy(in, DealEs.class);
        dealESDao.delete(dealES);
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_DEL, LogConstant.RESULT, LogConstant.SUCCESS, JSONUtil.toStr(in)));
        return ServiceResult.success();
    }

    @Override
    public ServiceResult grid(DealGridIn in) {
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_GRID, LogConstant.IN, JSONUtil.toStr(in)));
        // 构建查询
        NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder();
        // 多索引查询
        searchQuery.withIndices(EsConstant.INDEX_DEAL);
        // 组合查询，boost即为权重，数值越大，权重越大
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.multiMatchQuery(in.getAccount(), EsConstant.FIELD_DEAL_ACCOUNT).boost(3))
                .should(QueryBuilders.multiMatchQuery(in.getSerialNum(), EsConstant.FIELD_DEAL_SERIAL_NUM).boost(2))
                .should(QueryBuilders.multiMatchQuery(in.getRemark(), EsConstant.FIELD_DEAL_REMARK).boost(1));
        searchQuery.withQuery(queryBuilder);
        // 分页
        searchQuery.withPageable(PageRequest.of(in.getPageNum(), in.getPageSize()));
        // 执行查询
        Page<DealEs> result = esTemplate.queryForPage(searchQuery.build(), DealEs.class);
        log.info(StringUtil.join(BUSINESS_NAME, LogConstant.SERVICE, METHOD_GRID, LogConstant.RESULT, LogConstant.SUCCESS, JSONUtil.toStr(result)));
        return ServiceResult.success(result);
    }
}
